package mgodb

import (
	"github.com/facebookgo/inject"
	"github.com/globalsign/mgo"
	"github.com/globalsign/mgo/bson"
	"github.com/pkg/errors"
	"jgt-oper/src/model"
	"jgt-oper/src/schema"
	"jgt-oper/src/service/mongo"
	"time"
)

// cNotice 通知发布数据表
const cNotice = "oper_notice"

// Notice 通知发布管理
type Notice struct {
	DB *mongo.DB
}

// Init 初始化
func (a *Notice) Init(g *inject.Graph, db *mongo.DB) {
	a.DB = db

	// 初始化mongo索引
	a.DB.C(cNotice, func(c *mgo.Collection) error {
		//c.EnsureIndex(mgo.Index{
		//	Key:    []string{"record_id"},
		//	Unique: true,
		//})
		//c.EnsureIndexKey("_id")
		//c.EnsureIndexKey("level_code")
		//c.EnsureIndexKey("deleted")
		return nil
	})

	var val model.INotice = a
	g.Provide(&inject.Object{Value: val, Name: "INotice"})
}

// Create 创建通知
func (a *Notice) Create(item *schema.Notice) error {
	err := a.DB.C(cNotice, func(c *mgo.Collection) error {
		id, err := a.DB.IncrID(cNotice)
		if err != nil {
			return err
		}
		item.ID = id
		return c.Insert(item)
	})
	if err != nil {
		return errors.Wrapf(err, "创建数据发生错误")
	}

	return nil
}

// Get 获取详情
func (a *Notice) Get(recordID string) (*schema.Notice, error) {
	item := new(schema.Notice)
	err := a.DB.C(cNotice, func(c *mgo.Collection) error {
		return c.Find(bson.M{"record_id": recordID}).One(item)
	})
	if err != nil {
		if err == mgo.ErrNotFound {
			return nil, nil
		}
		return nil, errors.Wrapf(err, "精确查询数据发生错误")
	}
	return item, nil
}

// Update 更新数据
func (a *Notice) Update(recordID string, info map[string]interface{}) error {
	err := a.DB.C(cNotice, func(c *mgo.Collection) error {
		return c.Update(bson.M{"record_id": recordID}, bson.M{"$set": info})
	})
	if err != nil {
		return errors.Wrapf(err, "更新数据发生错误")
	}
	return nil
}

// QueryPage 查询分页
func (a *Notice) QueryPage(params *schema.NoticeQParams, pageIndex, pageSize uint) (int, []*schema.Notice, error) {

	query := bson.M{
		"deleted": 0,
	}

	if params.NoticeTitle != "" {
		query["notice_title"] = bson.M{"$regex": params.NoticeTitle}
	}
	if params.ReceiveGroupType != 0 {
		query["receive_group_type"] = params.ReceiveGroupType
	}
	if len(params.ReceiveGroup) > 0 {
		query["receive_group"] = bson.M{"$in": params.ReceiveGroup}
	}
	//	全部情况下
	if params.MessageMode == 0 && params.PushMode == 0 {
		query["notice_mode"] = bson.M{"$in": []int{1, 2, 3}}
	}
	//	必须包含推送方式的情况下
	if params.MessageMode == 0 && params.PushMode == 1 {
		query["notice_mode"] = bson.M{"$in": []int{1, 3}}
	}
	//	必须不包含推送形式的情况下
	if params.MessageMode == 0 && params.PushMode == 2 {
		query["notice_mode"] = bson.M{"$in": []int{0, 2}}
	}
	//	必须包含短信的情况下
	if params.MessageMode == 1 && params.PushMode == 0 {
		query["notice_mode"] = bson.M{"$in": []int{2, 3}}
	}
	//	必须短信和推送两种形式的情况下
	if params.MessageMode == 1 && params.PushMode == 1 {
		query["notice_mode"] = bson.M{"$in": []int{3}}
	}
	//	必须短信形式并且不含推送的情况下
	if params.MessageMode == 1 && params.PushMode == 2 {
		query["notice_mode"] = bson.M{"$in": []int{2}}
	}
	//	必须不含短信的情况下
	if params.MessageMode == 2 && params.PushMode == 0 {
		query["notice_mode"] = bson.M{"$in": []int{0, 1}}
	}
	//	必须不含短信并且一定含推送的情况下
	if params.MessageMode == 2 && params.PushMode == 1 {
		query["notice_mode"] = bson.M{"$in": []int{1}}
	}
	//	必须短信形式并且不含推送的情况下
	if params.MessageMode == 2 && params.PushMode == 2 {
		query["notice_mode"] = bson.M{"$in": []int{0}}
	}
	//
	if params.NoticeContent != "" {
		query["notice_content"] = bson.M{"$regex": params.NoticeContent}
	}
	//	设置查询时间
	if params.EndTime == 0 {
		params.EndTime = time.Now().Unix()
	}
	query["$and"] = []bson.M{{"created": bson.M{"$gte": params.StartTime}}, {"created": bson.M{"$lte": params.EndTime}}}
	switch params.Status {
	case 0:
	case 1:
		query["status"] = 1
	case 2:
		query["status"] = 2
	}

	var total int
	var items []*schema.Notice
	var err error
	err = a.DB.C(cNotice, func(c *mgo.Collection) error {
		total, err = c.Find(query).Count()
		if err != nil {
			return err
		}

		return c.Find(query).Sort("-created").Skip(int((pageIndex - 1) * pageSize)).Limit(int(pageSize)).All(&items)
	})
	if err != nil {
		return 0, nil, errors.Wrapf(err, "查询分页数据发生错误")
	}

	return total, items, nil
}
